﻿using System;
using System.Collections.Generic;
using HtmlTagInnerTextTests.Common;
using Microsoft.VisualStudio.TestTools.WebTesting;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WebAndLoadTestPluginsAndRules.Common;

namespace HtmlTagInnerTextTests
{


    /// <summary>
    ///This is a test class for FilterDependentRequestsPluginTest and is intended
    ///to contain all FilterDependentRequestsPluginTest Unit Tests
    ///</summary>
    [TestClass]
    public class FilterDependentRequestsPluginTest
    {
        /// <summary>
        ///A test for FilterDependentRequests
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void FilterDependentRequests_WhenHaveMatchingRequest_EnsureMatchesAreRemoved()
        {
            // Arrange
            ICollection<WebTestRequest> actualDependentRequests = new List<WebTestRequest>
                                                                            { 
                                                                                new WebTestRequest("foo"), 
                                                                                new WebTestRequest("bar")
                                                                            };
            ICollection<WebTestRequest> expectedDependendRequests = new List<WebTestRequest>();
            Func<string, bool> filterPredicate = r => true; // remove all!
            PredicateFilter filter = new PredicateFilter(filterPredicate);
            Action<WebTest, string> addCommentAction = NullAction;
            const bool addCommentOnRemoval = false;

            FakeFilterDependentRequestsPlugin plugin = new FakeFilterDependentRequestsPlugin(addCommentAction);
            WebTest webTest = new FakeWebTest();

            // Act
            plugin.TestFilterDependentRequests(webTest, actualDependentRequests, filter, addCommentOnRemoval);

            // Assert
            AssertHelpers.AssertCollectionsEqual(expectedDependendRequests, actualDependentRequests);
        }

        /// <summary>
        ///A test for FilterDependentRequests
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void FilterDependentRequests_WhenHaveNonMatches_EnsureNonMatchesAreNotRemoved()
        {
            // Arrange
            ICollection<WebTestRequest> actualDependentRequests = new List<WebTestRequest>
                                                                            { 
                                                                                new WebTestRequest("foo"), 
                                                                                new WebTestRequest("bar")
                                                                            };
            ICollection<WebTestRequest> expectedDependendRequests = new List<WebTestRequest>(actualDependentRequests);
            Func<string, bool> filterPredicate = r => false; // remove none!
            PredicateFilter filter = new PredicateFilter(filterPredicate);
            Action<WebTest, string> addCommentAction = NullAction;
            const bool addCommentOnRemoval = false;

            FakeFilterDependentRequestsPlugin plugin = new FakeFilterDependentRequestsPlugin(addCommentAction);
            WebTest webTest = new FakeWebTest();

            // Act
            plugin.TestFilterDependentRequests(webTest, actualDependentRequests, filter, addCommentOnRemoval);

            // Assert
            AssertHelpers.AssertCollectionsEqual(expectedDependendRequests, actualDependentRequests);
        }

        /// <summary>
        ///A test for FilterDependentRequests
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void FilterDependentRequests_WhenRemovingRequestsAndCommentsEnabled_EnsureCommentsAreAdded()
        {
            // Arrange
            ICollection<WebTestRequest> actualDependentRequests = new List<WebTestRequest>
                                                                            { 
                                                                                new WebTestRequest("foo"), 
                                                                                new WebTestRequest("bar")
                                                                            };
            Func<string, bool> filterPredicate = r => true; // remove all!
            PredicateFilter filter = new PredicateFilter(filterPredicate);
            int commentCount = 0;
            Action<WebTest, string> addCommentAction = (wt, s) => commentCount++;
            const bool addCommentOnRemoval = true;

            FakeFilterDependentRequestsPlugin plugin = new FakeFilterDependentRequestsPlugin(addCommentAction);
            WebTest webTest = new FakeWebTest();

            // Act
            plugin.TestFilterDependentRequests(webTest, actualDependentRequests, filter, addCommentOnRemoval);

            // Assert
            Assert.AreEqual(2, commentCount, "Incorrect number of comments added");
        }
        /// <summary>
        ///A test for FilterDependentRequests
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void FilterDependentRequests_WhenRemovingAndCommentsDisabled_EnsureCommentsNotAreAdded()
        {
            // Arrange
            ICollection<WebTestRequest> actualDependentRequests = new List<WebTestRequest>
                                                                            { 
                                                                                new WebTestRequest("foo"), 
                                                                                new WebTestRequest("bar")
                                                                            };
            Func<string, bool> filterPredicate = r => true; // remove all!
            PredicateFilter filter = new PredicateFilter(filterPredicate);
            int commentCount = 0;
            Action<WebTest, string> addCommentAction = (wt, s) => commentCount++;
            const bool addCommentOnRemoval = false;

            FakeFilterDependentRequestsPlugin plugin = new FakeFilterDependentRequestsPlugin(addCommentAction);
            WebTest webTest = new FakeWebTest();

            // Act
            plugin.TestFilterDependentRequests(webTest, actualDependentRequests, filter, addCommentOnRemoval);

            // Assert
            Assert.AreEqual(0, commentCount, "Incorrect number of comments added");
        }


        /// <summary>
        ///A test for FilterDependentRequests
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void FilterDependentRequests_WhenDependentRequestsNull_EnsureThrowsArgumentException()
        {
            // Arrange
            const ICollection<WebTestRequest> actualDependentRequests = null;
            Func<string, bool> filterPredicate = r => true; // remove all!
            PredicateFilter filter = new PredicateFilter(filterPredicate);
            int commentCount = 0;
            Action<WebTest, string> addCommentAction = (wt, s) => commentCount++;
            const bool addCommentOnRemoval = false;

            FakeFilterDependentRequestsPlugin plugin = new FakeFilterDependentRequestsPlugin(addCommentAction);
            WebTest webTest = new FakeWebTest();

            // Act
            Action action = () => plugin.TestFilterDependentRequests(webTest, actualDependentRequests, filter, addCommentOnRemoval);

            // Assert
            AssertHelpers.ThrowsArgumentException<ArgumentNullException>(action, "dependentRequests");
        }
        /// <summary>
        ///A test for FilterDependentRequests
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void FilterDependentRequests_WhenWebTestNull_EnsureThrowsArgumentNullException()
        {
            // Arrange
            ICollection<WebTestRequest> actualDependentRequests = new List<WebTestRequest>();
            Func<string, bool> filterPredicate = r => true; // remove all!
            PredicateFilter filter = new PredicateFilter(filterPredicate);
            int commentCount = 0;
            Action<WebTest, string> addCommentAction = (wt, s) => commentCount++;
            const bool addCommentOnRemoval = false;

            FakeFilterDependentRequestsPlugin plugin = new FakeFilterDependentRequestsPlugin(addCommentAction);
            const WebTest webTest = null;

            // Act
            Action action = () => plugin.TestFilterDependentRequests(webTest, actualDependentRequests, filter, addCommentOnRemoval);

            // Assert
            AssertHelpers.ThrowsArgumentException<ArgumentNullException>(action, "webTest");
        }

        /// <summary>
        ///A test for Filter
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void Filter_WhenFilterTextNonNull_EnsureCallingFilterFactory()
        {
            // Arrange
            const string expectedFilterText = "theFilterText";
            const FilterMethod expectedFilterMethod = FilterMethod.Regex;
            const bool expectedIgnoreCase = true;

            bool isCalled = false;

            FakeFilterFactory fakeFilterFactory = new FakeFilterFactory(
                (filterText, filterMethod, ignoreCase) =>
                {
                    isCalled = true;
                    return null;
                }
            );
            FakeFilterDependentRequestsPlugin appendQueryStringValue = new FakeFilterDependentRequestsPlugin(NullAction, fakeFilterFactory)
            {
                FilterText = expectedFilterText,
                FilterMethod = expectedFilterMethod,
                IgnoreCase = expectedIgnoreCase,
            };

            // Act
            Filter actual = appendQueryStringValue.Filter;

            // Assert
            Assert.IsTrue(isCalled);
        }

        /// <summary>
        ///A test for Filter
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void Filter_WhenFilterTextNonNull_EnsureFilterTextIsPassedToFactory()
        {
            // Arrange
            const string expectedFilterText = "theFilterText";
            const FilterMethod expectedFilterMethod = FilterMethod.Regex;
            const bool expectedIgnoreCase = true;

            string actualFilterText = null;

            FakeFilterFactory fakeFilterFactory = new FakeFilterFactory(
                (filterText, filterMethod, ignoreCase) =>
                {
                    actualFilterText = filterText;
                    return null;
                }
            );
            FakeFilterDependentRequestsPlugin appendQueryStringValue = new FakeFilterDependentRequestsPlugin(NullAction, fakeFilterFactory)
            {
                FilterText = expectedFilterText,
                FilterMethod = expectedFilterMethod,
                IgnoreCase = expectedIgnoreCase,
            };

            // Act
            Filter actual = appendQueryStringValue.Filter;

            // Assert
            Assert.AreEqual(expectedFilterText, actualFilterText);
        }

        /// <summary>
        ///A test for Filter
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void Filter_WhenFilterTextNonNull_EnsureFilterMethodIsPassedToFactory()
        {
            // Arrange
            const string expectedFilterText = "theFilterText";
            const FilterMethod expectedFilterMethod = FilterMethod.Regex;
            const bool expectedIgnoreCase = true;

            FilterMethod actualFilterMethod = (FilterMethod)(-1);

            FakeFilterFactory fakeFilterFactory = new FakeFilterFactory(
                (filterText, filterMethod, ignoreCase) =>
                {
                    actualFilterMethod = filterMethod;
                    return null;
                }
            );
            FakeFilterDependentRequestsPlugin appendQueryStringValue = new FakeFilterDependentRequestsPlugin(NullAction, fakeFilterFactory)
            {
                FilterText = expectedFilterText,
                FilterMethod = expectedFilterMethod,
                IgnoreCase = expectedIgnoreCase,
            };

            // Act
            Filter actual = appendQueryStringValue.Filter;

            // Assert
            Assert.AreEqual(expectedFilterMethod, actualFilterMethod);
        }
        /// <summary>
        ///A test for Filter
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void Filter_WhenFilterTextNonNull_EnsureIgnoreCaseIsPassedToFactory()
        {
            // Arrange
            const string expectedFilterText = "theFilterText";
            const FilterMethod expectedFilterMethod = FilterMethod.Regex;
            const bool expectedIgnoreCase = true;

            bool actualIgnoreCase = false;

            FakeFilterFactory fakeFilterFactory = new FakeFilterFactory(
                (filterText, filterMethod, ignoreCase) =>
                {
                    actualIgnoreCase = ignoreCase;
                    return null;
                }
            );
            FakeFilterDependentRequestsPlugin appendQueryStringValue = new FakeFilterDependentRequestsPlugin(NullAction, fakeFilterFactory)
            {
                FilterText = expectedFilterText,
                FilterMethod = expectedFilterMethod,
                IgnoreCase = expectedIgnoreCase,
            };

            // Act
            Filter actual = appendQueryStringValue.Filter;

            // Assert
            Assert.AreEqual(expectedIgnoreCase, actualIgnoreCase);
        }


        private static void NullAction(WebTest webTest, string param)
        {

        }
    }
}